﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SuraQR.Controller;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using SuraQR.Config;
using System.Collections;
using SuraQR.Bean;

namespace SuraQR
{
    public partial class TestQRCode : Form , IQRCodeReaderListenner
    {
        private QRCodeReaderService qr;
        private SOROR12011 _deserail;
        delegate void SetTextCallback(string text);
        private ArrayList qrListData;
        private string currentID = "";
        private int currentMaxSize = 0;
        Dictionary<int, String> dictionary = new Dictionary<int, String>();
        private bool[] statReader;

        public TestQRCode()
        {
            InitializeComponent();

            qr = new QRCodeReaderService();
            qr.init();
            qr.setListener(this);
            qrListData = new ArrayList();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            label2.Text = qr.COM_PORT_NAME1 + " : Connect ";
            button1.Enabled = false;           
            qr.start();
            qrListData.Clear();
            currentID = "";
            currentMaxSize = 0;
            dictionary.Clear();
            statReader = new bool[10];

            button2.Enabled = false;         
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (qr.IsStart)
            {
                button1.Enabled = true;
                qr.close();
            }
            
        }

        public void readDataQR(String rawData)
        {
            //Debug.WriteLine(" in form : " + rawData);
           

            // check length
            if (rawData.Length < 20)
            {
                Debug.WriteLine("error size");
                msg("Error size");
                return;
            }
            //check header data
            string h = rawData.Substring(0,PropertiesConfig._Header.Length);
            if (!PropertiesConfig._Header.Equals(h))
            {
                Debug.WriteLine("not SR QR");
                msg("QR not for this application");
            }

            //SR1200#1.110#7:7#9d7cf70e-7842-4155-9769-a198d6fba5bc#
            //version
            string[] str = rawData.Split('#');
            if(!PropertiesConfig._AppVersin.Equals(str[1]))
            {
                Debug.WriteLine("version not math");
                msg("version not math");
            }

            // push data
            //first
            if (qrListData.Count == 0)
            {
                currentID = str[3];
                currentMaxSize = Convert.ToInt32(str[2].Split(':')[1]);
            }
            // exist
            if (qrListData.Count > 0)
            {
                // check uid
                if (!currentID.Equals(str[3]))
                {
                    Debug.WriteLine("Not same UUID QRCODE");
                    msg("not same QR part ID");
                    return;
                }

            }

            // insert DATA
            string currentStr = rawData;
            int currentIndex = Convert.ToInt32(str[2].Split(':')[0]);
            Debug.WriteLine("Current INDEX : " + currentIndex);

            bool isExist = qrListData.Contains(currentStr);
           
            if (isExist)
            {
                Debug.WriteLine("Duplicate index : " + currentIndex);
                msg("scan duplicate");
            }
            else
            {
                qrListData.Add(currentStr);
                dictionary.Add(currentIndex, currentStr);
                Debug.WriteLine("Insert index : " + currentIndex);
                statReader[currentIndex - 1] = true;
                 msg("part " + currentIndex + "  => complete");
            }

            Debug.WriteLine(" > " + qrListData.Count + " : " + currentMaxSize);
            if (qrListData.Count == currentMaxSize)
            {
                Debug.WriteLine("Scan is finish");
                msg("complete");
                onfinish();
            }


            /// display stat
            string s = "";
            for (int i = 0; i < currentMaxSize;i++ )
            {
                s += "[" + (i+1) + "=" + statReader[i] + "]  ";
            }
            SetTextCallback bb = new SetTextCallback(SetText);
            this.Invoke(bb, new object[] { s });

           
            
        }

        private void SetText(string text)
        {

                this.label1.Text = text;
         
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Bean.SOROR12011 tmp = new Bean.SOROR12011();
            Bean.F1Address addr = new Bean.F1Address();
            addr.Name = "Arm";
            tmp.Addr = addr;

            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream,tmp);
            Debug.WriteLine( "LENGTH : " +  stream.ToArray().Length ) ;
            string base64 = Convert.ToBase64String(stream.ToArray());
            Debug.WriteLine("Base64:" + base64);
            stream.Close();

            stream = new MemoryStream(stream.ToArray());
            Bean.SOROR12011 deserail = (Bean.SOROR12011)formatter.Deserialize(stream);
            Debug.WriteLine(deserail.Addr.Name);
            stream.Close();
            
            // base64
            byte[] b64 = Convert.FromBase64String(base64);
            Debug.WriteLine("Length : " + b64.Length);
            stream = new MemoryStream(b64);
            deserail = (Bean.SOROR12011)formatter.Deserialize(stream);
            Debug.WriteLine(deserail.Addr.Name);
            stream.Close();
        }

        private void TestQRCode_Load(object sender, EventArgs e)
        {
            comboBox1.SelectedIndex = 0;
        }

        public void onError(Exception e)
        {
            MessageBox.Show(e.ToString());
            button1.Enabled = true;
            label2.Text = "Error : " + qr.COM_PORT_NAME1;
        }

        private void onfinish(){
            //close
            disablebutton dd = new disablebutton(disables);
            

            if (qr.IsStart)
            {
                qr.close();
            }
            
            //make string
            StringBuilder b = new StringBuilder();
            for(int i = 1 ; i <= currentMaxSize ; i++)
            {
                b.Append(dictionary[i].Split('#')[4]);
            
            }

            //
            string base64 = b.ToString();
            Debug.WriteLine("bsize : " + base64.Length);
            // base64
            byte[] b64 = Convert.FromBase64String(base64);
            Debug.WriteLine("Length : " + b64.Length);
            Stream stream = new MemoryStream(b64);
            BinaryFormatter formatter = new BinaryFormatter();
            Deserail = (SOROR12011)formatter.Deserialize(stream);
            
            stream.Close();

            // show 
            
            this.Invoke(dd);
        }

        public delegate void disablebutton();
        public void disables()
        {
            button1.Enabled = true;
            button2.Enabled = false;

            luncher l = new luncher();
            //Debug.WriteLine("##########" + Deserail.Tax);
            //Debug.WriteLine("@@@@@@@@@@" +Deserail.Tax.Data14);
            l.showWithData(Deserail);
        }

        public SOROR12011 Deserail
        {
            get { return _deserail; }
            set { _deserail = value; }
        }

        public delegate void errorMsg(String msg);
        public void error_Msg(String msg)
        {
            label2.Text = msg;
        }
        public void msg(string msg)
        {
            errorMsg err = new errorMsg(error_Msg);
            this.Invoke(err, new object[] { msg });
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
           string p = comboBox1.Text;
           qr.COM_PORT_NAME1 = p;
           qr.init();
           label2.Text = "set port COM : " + p;
        }
    }
}
